package ma.ensao.evalmetrics.controller.metrics;

import ma.ensao.evalmetrics.model.Caracteristiques;
import ma.ensao.evalmetrics.model.Metriques;
import ma.ensao.evalmetrics.model.Propriete;
import ma.ensao.evalmetrics.model.Result;
import ma.ensao.evalmetrics.model.Subcarac;
/*
* Calcul des caratcteristiques et propriet�s de qualit� par les metriques
*/
public class Calcule {
	private double ahf = 0;
	private double apf = 0;
	private double cloc = 0;
	private double cyclo = 0;
	private double dit = 0;
	private double loc = 0;
	private double mhf = 0;
	private double mpf = 0;
	private double noc = 0;
	private double nom = 0;
	private double rfc = 0;
	private double wmc = 0;
	private double pof = 0;
	private double abs = 0;
	private double tcc = 0;
	private double mpc = 0;
	private double i = 0;
	private double d = 0;
	private double ca = 0;
	private double ce = 0;
    private double noi=0;
    private double classes=1;

    
	double heritage = 0;//
	double coupling = 0;
	double abstraction = 0;//
	double size = 0;//
	double composition = 0;
	double encapsulation = 0;//
	double modularite = 0;
	double precision = 0;
	double consistence = 0;
	double cohesion = 0;
	double tolerence = 0;
	double instabilite = 0;
	double dependence = 0;
	double complexite = 0;
	double message = 0;//
	double specialisation = 0;
	double sizemethodes = 0;
	double stabilite = 0;
	double distance = 0;

	private double Convenance;
	private double Exactitude;
	private double Interoperabilite;
	private double Securite;
	private double Compliance;
	private double Maturite;
	private double FausseTolerance;
	private double Recoverabilite;
	private double Clarete;
	private double learnabilite;
	private double Attractivite;
	private double Comportement_time;
	private double Utilisation_Ressource;
	private double Variabilite;
	private double Analyse;
	private double Stabilite;
	private double Testabilite;
	private double Adabtabilite;
	private double Instabilite;
	private double Conformite;
	private double Remplacabilite;

	private double Fonctionnalite;
	private double Reliabilite;
	private double Usabilite;
	private double Efficacite;
	private double Maintenabilite;
	private double Portabilite;

	public Metriques calculMetrique(Metriques met, Result resultat) {
		System.out.println("test calcul" + resultat.getNOC());
		ahf = resultat.getAHF() * met.getAHF();
		apf = resultat.getAPF() * met.getAPF();
		cloc = resultat.getCLOC() * met.getCLOC();
		cyclo = resultat.getCyclo() * met.getCyclo();
		dit = resultat.getDit() * met.getDIT();
		loc = resultat.getLOC() * met.getLOC();
		mhf = resultat.getMHF() * met.getMHF();
		mpf = resultat.getMPF() * met.getMPF();
		System.out.println(resultat.getNOC()+"              "+met.getNOC());
		noc = resultat.getNOC() * met.getNOC();
		nom = resultat.getNOM() * met.getNOM();
		rfc = resultat.getRFC() * met.getRFC();
		//wmc = resultat.getWMC() * met.getWMC();
		pof = resultat.getPOF() * met.getPOF();
		abs = resultat.getAbs() * met.getAbs();
		tcc = resultat.getTCC() * met.getTCC();
		mpc = resultat.getMPC() * met.getMPC();
		i = resultat.getI() * met.getI();
		d = resultat.getD() * met.getD();
		noi = resultat.getNOI() * met.getNOI();
		ca = resultat.getCa() * met.getCa();
		ce = resultat.getCe()* met.getCe();
		classes = resultat.getClasses() * met.getClasses();
		met.setAHF(ahf);
		met.setAPF(apf);
		met.setCLOC(cloc);
		met.setCyclo(cyclo);
		met.setDIT(dit);
		met.setLOC(loc);
		met.setMHF(mhf);
		met.setMPF(mpf);
		met.setNOC(noc);
		met.setNOM(nom);
		met.setRFC(rfc);
		met.setWMC(wmc);
		met.setPOF(pof);
		met.setAbs(abs);
		met.setMPC(mpc);
		met.setTCC(tcc);
		met.setI(i);
		met.setD(d);
		met.setNOI(noi);
		met.setCa(ca);
		met.setCe(ce);
		met.setClasses(classes);
		
		return met;

	}

	public Propriete calculPropriete(Propriete prop) {
		System.out.println("test calcul" + prop.getHeritage());
		heritage = (double) Math.round(prop.getHeritage() * ( dit) 
				* 100) / 100;//
		coupling = (double) Math.round(prop.getCoupling() * (rfc+ca+ce)/3*100) / 100;//need to add rfc+ca+ce
		abstraction = (double) Math.round(prop.getAbstraction() * abs * 100) / 100;//
		composition = (double) Math.round(prop.getComposition() * 100) / 100;
		encapsulation = (double) Math.round(prop.getEncapsulation()
				* ahf  * 100) / 100;//
		modularite = (double) Math.round(prop.getModularite() * 100) / 100;
		precision = (double) Math.round(prop.getPrecision() * 100) / 100;
		consistence = (double) Math.round(prop.getConsistence() * 100) / 100;
		cohesion = (double) Math.round(prop.getCohesion() * tcc * 100) / 100; // = lcom ( verify if lcom is tcc)	
		tolerence = (double) Math.round(prop.getTolerence() * 100) / 100;
		instabilite = (double) Math.round(prop.getInstabilite() * i * 100) / 100;
		dependence = (double) Math.round(prop.getDependence() * d*100) / 100;
		complexite = (double) Math.round(prop.getComplexite() * ( cyclo)
				* 100) / 100;
		size = (double) Math.round(prop.getSize() * (complexite+loc + cloc + nom) / 4 //size=complex+nom+cloc(moy)+sloc(moy) 
				* 100) / 100;//
		message = (double) Math
				.round(prop.getMessage() * (rfc)  * 100) / 100;//
		specialisation = (double) Math.round(prop.getSpecialisation() * 100) / 100;
		sizemethodes = (double) Math.round(prop.getSizemethodes() * 100) / 100;
		stabilite = (double) Math.round(prop.getStabilite() * 100) / 100;

		prop.setSize(size);
		prop.setComplexite(complexite);
		prop.setHeritage(heritage);
		prop.setEncapsulation(encapsulation);
		prop.setAbstraction(abstraction);
		prop.setMessage(message);
		prop.setCohesion(cohesion);
		prop.setCoupling(coupling);
		prop.setInstabilite(instabilite);
		prop.setDependence(dependence);
		
		return prop;

	}

	public Subcarac calculSubcarac(Subcarac sub) {

		Convenance = sub.getConvenance();
		Exactitude = sub.getExactitude();
		Interoperabilite = (double) Math.round(sub.getInteroperabilite()
				* (heritage + coupling) / 2 * 100) / 100;
		Securite = (double) Math
				.round(sub.getSecurite()
						* (abstraction + heritage + composition
								+ coupling + encapsulation) / 5 * 100) / 100;
		Compliance = sub.getCompliance();
		Maturite = (double) Math.round(sub.getMaturite()
				* (modularite + precision + consistence + cohesion) / 4 * 100) / 100;
		FausseTolerance = (double) Math.round(sub.getFausseTolerance()
				* (tolerence + instabilite + dependence) / 3 * 100) / 100;
		Recoverabilite = sub.getRecoverabilite() * (complexite);
		Clarete = sub.getClarete();
		learnabilite = sub.getLearnabilite();
		Attractivite = (double) Math.round(sub.getAttractivite()
				* (2 * modularite + message) / 2 * 100) / 100;
		Comportement_time = sub.getComportement_time();
		Utilisation_Ressource = sub.getUtilisation_Ressource();
		Variabilite = (double) Math.round(sub.getVariabilite()
				* (coupling + heritage + specialisation + modularite
						+ complexite) / 5 * 100) / 100;
		Analyse = (double) Math.round(sub.getAnalyse()
				* (coupling + heritage + specialisation + modularite
						 + sizemethodes) / 5 * 100) / 100;
		Stabilite = (double) Math.round(sub.getStabilite()
				* (dependence + stabilite + coupling) / 3 * 100) / 100;
		Testabilite = (double) Math.round(sub.getTestabilite()
				* (complexite + modularite) / 2 * 100) / 100;
		Adabtabilite = sub.getAdabtabilite()*complexite;
		Instabilite = sub.getInstabilite()*i;
		Conformite = sub.getConformite() * (modularite);
		Remplacabilite = sub.getRemplacabilite();

		sub.setConvenance(Convenance);
		sub.setExactitude(Exactitude);
		sub.setInteroperabilite(Interoperabilite);
		sub.setSecurite(Securite);
		sub.setCompliance(Compliance);
		sub.setMaturite(Maturite);
		sub.setFausseTolerance(FausseTolerance);
		sub.setRecoverabilite(Recoverabilite);
		sub.setClarete(Clarete);
		sub.setLearnabilite(learnabilite);
		sub.setAttractivite(Attractivite);
		sub.setComportement_time(Comportement_time);
		sub.setUtilisation_Ressource(Utilisation_Ressource);
		sub.setVariabilite(Variabilite);
		sub.setAnalyse(Analyse);
		sub.setStabilite(Stabilite);
		sub.setTestabilite(Testabilite);
		sub.setAdabtabilite(Adabtabilite);
		sub.setInstabilite(Instabilite);
		sub.setConformite(Conformite);
		sub.setRemplacabilite(Remplacabilite);

		return sub;

	}

	public Caracteristiques calculCaracteristiques(Caracteristiques carac) {

		Fonctionnalite = (double) Math
				.round(carac.getFonctionnalite()
						* (Convenance + Exactitude + Interoperabilite
								+ Securite + Compliance) / 5 * 100) / 100;
		Reliabilite = (double) Math.round(carac.getReliabilite()
				* (Maturite + FausseTolerance + Recoverabilite) / 3 * 100) / 100;
		Usabilite = (double) Math.round(carac.getUsabilite()
				* (Clarete + learnabilite + Attractivite) / 3 * 100) / 100;
		Efficacite = (double) Math.round(carac.getEfficacite()
				* (Comportement_time + Utilisation_Ressource) / 2 * 100) / 100;
		Maintenabilite = (double) Math.round(carac.getMaintenabilite()
				* (Variabilite + Analyse + Stabilite + Testabilite) / 4 * 100) / 100;
		Portabilite = (double) Math.round(carac.getPortabilite()
				* (Adabtabilite + Instabilite + Conformite + Remplacabilite)
				/ 4 * 100) / 100;

		carac.setFonctionnalite(Fonctionnalite);
		carac.setReliabilite(Reliabilite);
		carac.setUsabilite(Usabilite);
		carac.setEfficacite(Efficacite);
		carac.setMaintenabilite(Maintenabilite);
		carac.setPortabilite(Portabilite);
		return carac;

	}
}